/*
 * lock.h
 *
 *  Created on: 2008-8-12
 *      Author: fanliangliang
 */

#ifndef LOCK_H_
#define LOCK_H_

#include "mutex.h"

BEGIN_NAMESPACE_TOXIC

namespace detail {

	template <typename MutexType>
	class ScopedLock {
	public:
		explicit ScopedLock(MutexType& mutex, bool initiallyLocked = true)
		:_mutex(mutex)
		,_isLocked(false) {
			if (initiallyLocked) {
				lock();
			}
		}

		~ScopedLock() {
			unlock();
		}

		bool isLocked() const {
			return _isLocked;
		}

		void lock() {
			if (!_isLocked) {
				_mutex.lock();
				_isLocked = true;
			}
		}

		void unlock() {
			if (_isLocked) {
				_mutex.unlock();
				_isLocked = false;
			}
		}

		bool trylock() {
			if (_isLocked) {
				return false;
			}
			_isLocked = _mutex.trylock();
			return _isLocked;
		}

		typename MutexType::handle_type* internal() {
			return _mutex.internal();
		}

	private:
		MutexType& _mutex;
		bool _isLocked;
	};

} // namespace detail

typedef detail::ScopedLock<Mutex> ScopedLock;

END_NAMESPACE_TOXIC

#endif /* LOCK_H_ */
